#!/usr/bin/env python

import sys
import osg2 as osg

def main():
   osg.osgInit(sys.argv)

   fcf = osg.FieldContainerFactory.the()
   ff = osg.FieldFactory.the()

   field_ptr = ff.createField("SFVec3f")
   vec3f_ptr = field_ptr
   assert(vec3f_ptr is not None)

   # Check vector interface
   vec3f_ptr.getValue().setValues(1, 2, 3)
   pos = vec3f_ptr.getValue()
   pos[2] = 10
#   vec3f_ptr.getValue() = pos  # May not be necessary

   int32_ptr = ff.createField("SFInt32")
   assert(int32_ptr is not None)

   int32_val = int32_ptr.getValue()
#   int32_ptr.getValue() = (int32_val + 10) # XXX: This probably doesn't work
   int32_ptr.setValue(20)

   # Assign with abstrvaule interface
   vec3f_ptr2 = ff.createField("SFVec3f")
   field_ptr.setAbstrValue(vec3f_ptr2)

   # Multifield
   # Quaternion
   # Matrix

   # - Creating fc from factory
   #    - Create Field container
   #    - Create None
   #    - Create NoneCore
   node_fc = fcf.createFieldContainer("Node")
   node_ptr = fcf.createNode("Node")
   node_ptr = osg.Node.create()
   node_core_ptr = fcf.createNodeCore("Group")

   # Groups??
   #    - List all groups
   # List all groups
#   print "Groups:"
#   num_groups = fcf.getNumGroups()
#   for gid in xrange(num_groups):
#      print "%d: %s" % (gid, fcf.findGroupName(gid))
#   print

   print "Field Containers:"
   num_fc_types = fcf.getNumTypes()
   for i in xrange(num_fc_types):
      fc_type = fcf.findType(i)
      if fc_type is not None:
         print "  %d: %s" % (i, fc_type.getCName())
   print

   # FieldContainerType
   #    - Output full description of type
   #       - Details of each FieldDescription
   win_fc_type = fcf.findType("Window")
   descFCType(win_fc_type)

   # Field Container
   #  - Gettype
   #  - get type id
   #  - get groupid
   #  - GetClassType()
   print "Viewport FieldContainer:"
   vp_fc = fcf.createFieldContainer("Viewport")
   print "   type id:%s\n   type name:%s" % (vp_fc.getTypeId(),
                                             vp_fc.getTypeName())

   vp_fc_type = vp_fc.getType()
   print "Viewport type:"
   descFCType(vp_fc_type)

   # Fields
   # - Reflective:
   #    - Get field type
   #    - get content type (and display)
   #    - Get cardinality

   win_fc = fcf.createFieldContainer("PassiveWindow")
   assert(win_fc is not None)  # XXX: Is this equivalent to the C++ version?

   width_field = win_fc.getField("width")
   assert(width_field is not None)

   print "Window width field:"
   descField(width_field)

   # Get the value for the field
   width_val = getFieldValue(width_field)
   width_val += 20
   setFieldValue(width_field, width_val)

   # - Set and get values
   #    - setAbstrValue
   #    - Set with all primitive types
#   win_ptr = osg.PassiveWindow.create()
#   width = win_ptr.getWidth()
#   sf_width = win_ptr.getSFWidth()
#   width = sf_width.getValue()
#
#   win_ptr.setWidth(width + 20)
#   win_ptr.getSFWidth.setValue(width + 20)

   # - Nodes
   #    - Add/remove children
   #    - Add/remove nodecores

   print "\n\nDone..."
   osg.osgExit()

def descFCType(fcType):
   fc_type_name = fcType.getCName()
   fc_type_id   = fcType.getId()

   print "FC Type: [%d] %s" % (fc_type_id, fc_type_name)
   print "  Init:%s" % fcType.isInitialized(),
   print " Abstract:%s" % fcType.isAbstract(),
   print " Node:%s" % fcType.isNode(),
   print " NodeCore:%s" % fcType.isNodeCore(),
   print " Attach:%s" % fcType.isAttachment()

   num_fields = fcType.getNumFieldDescs()
   print "  Fields:%d" % num_fields
   for i in xrange(num_fields):
      print "    %d:" % i,
      descFDesc(fcType.getFieldDescription(i))
      print
   print

def descFDesc(fieldDesc):
   if fieldDesc is None:
      print "N/A",
   else:
      fc_name = fieldDesc.getCName()
      field_id = fieldDesc.getFieldId()
      type = fieldDesc.getFieldType()
      type_name = type.getCName()
      print "%s  id:%d  type:%s" % (fc_name, field_id, type_name),

def descField(field):
   descFieldType(field.getType())
   print " content: %s" % field.getContentType().getCName()

def descFieldType(fieldType):
   field_type_name = fieldType.getCName()
   multi = (osg.FieldType.Cardinality.MULTI_FIELD == fieldType.getCardinality())
   print "name: %s  multi:%d" % (field_type_name, multi),

def setFieldValue(field, newValue):
   field.setValue(newValue)

def getFieldValue(field):
   return field.getValue()

if __name__ == '__main__':
   main()
